package edu.harvard.s3xyback;

import edu.harvard.s3xyback.S3xyBack;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.*;
import java.util.Random;
import javax.crypto.spec.PBEParameterSpec;
import java.security.KeyPairGenerator;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.*;

// An RSA key generator if we need it later--currently not in use at this phase
public class RSAKeyFactory {
    // generate key pair
    public static final String MYPBEALG = "PBEWithSHA1AndDESede";

    public static byte[] generateKey(String password, String keyFile, String saltFile) {
        try{
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(1024);
            KeyPair keyPair = keyPairGenerator.genKeyPair();

            // extract the encoded private key, this is an unencrypted PKCS#8 private key
            byte[] encodedprivkey = keyPair.getPrivate().getEncoded();

            // We must use a PasswordBasedEncryption algorithm in order to encrypt the private key, you may use any common algorithm supported by openssl, you can check them in the openssl documentation http://www.openssl.org/docs/apps/pkcs8.html
            int count = 20;// hash iteration count
            Random random = new Random();
            byte[] salt = new byte[8];
            random.nextBytes(salt);

            // Create PBE parameter set
            PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);
            PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
            SecretKeyFactory keyFac = SecretKeyFactory.getInstance(MYPBEALG);
            SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);

            Cipher pbeCipher = Cipher.getInstance(MYPBEALG);

            // Initialize PBE Cipher with key and parameters
            pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);

            // Encrypt the encoded Private Key with the PBE key
            byte[] ciphertext = pbeCipher.doFinal(encodedprivkey);

            // Now construct  PKCS #8 EncryptedPrivateKeyInfo object
            AlgorithmParameters algparms = AlgorithmParameters.getInstance(MYPBEALG);
            algparms.init(pbeParamSpec);
            EncryptedPrivateKeyInfo encinfo = new EncryptedPrivateKeyInfo(algparms, ciphertext);

            // save encrypted private key to file
            FileOutputStream fout_key = new FileOutputStream(keyFile);
            fout_key.write(encinfo.getEncoded());
            fout_key.close();

            // save salt to file
            FileOutputStream fout_salt = new FileOutputStream(saltFile);
            fout_salt.write(salt);
            fout_salt.close();

            // and here we have it! a DER encoded PKCS#8 encrypted key!
            return encinfo.getEncoded();
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static void main(String[] args) throws Exception {
        byte[] key_out = generateKey("blah blah blahxxxxxxxxxxxx", "C:\\Users\\ayoung01\\Dropbox\\s3xyback\\java\\src\\edu\\harvard\\s3xyback\\.aws_key", "C:\\Users\\ayoung01\\Dropbox\\s3xyback\\java\\src\\edu\\harvard\\s3xyback\\.aws_salt");
        //generateKey("blah blah blahxxxxxxxxxxxx", "/Users/jonathon/.aws_key_2", "/Users/jonathon/.aws_salt_2");
        //byte[] key_in = readKey("/Users/jonathon/.aws_key_1").getEncoded();

        //System.out.println(key_in.length);
        //System.out.println(key_in.equals(key_out));

    }
}
